package com.qf.controller;

import com.alibaba.fastjson.JSONObject;
import com.qf.captcha.CaptchaCodeManager;
import com.qf.pojo.DtsAdmin;
import com.qf.service.DtsAdminService;
import com.qf.service.DtsPermissionService;
import com.qf.service.DtsRoleService;
import com.qf.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


@RestController
@CrossOrigin
@RequestMapping("/admin/auth")
@Slf4j
public class AdminAuthController {
    //注入service对象
    @Autowired
    private DtsAdminService adminService;

    @Autowired
    private DtsRoleService roleService;

    @Autowired
    private DtsPermissionService permissionService;
    /**
     * 验证码
     */
    @GetMapping("/captchaImage")
    public Object captchaImage() throws IOException {

        //1. 生成随机字串--4位数验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2uuid
        String uuid = UUID.randomUUID(true).toString();
        //3验证码图片
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(111,36,outputStream,code);
        //4验证码存放到session中，uuid就是key
        CaptchaCodeManager.addToCache(uuid,code,null);//null默认时间3分钟


        Map<String,Object> result =new HashMap<>();
        result.put("img", Base64.encode(outputStream.toByteArray()));
        result.put("uuid",uuid);
        outputStream.close();
        return ResponseUtil.ok(result);
    }
    /**
     * 登录login
     */
    @PostMapping("/login")
    public Object login(@RequestBody String body){
        //1从前端传来的json串中提取出用户名、密码、验证码
        String username = JacksonUtil.parseString(body, "username");
        String passwordold = JacksonUtil.parseString(body, "password");
        String code = JacksonUtil.parseString(body, "code");
        String uuid = JacksonUtil.parseString(body, "uuid");
        //2后端判空验证
//        //3校验验证码是否正确
        String cachedCaptcha = CaptchaCodeManager.getCachedCaptcha(uuid);
        if (!code.equalsIgnoreCase(cachedCaptcha)){
            return AdminResponseUtil.fail(AdminResponseCode.AUTH_CAPTCHA_ERROR);
        }
        //密码加密
        Md5Hash password = new Md5Hash(passwordold,username,1024);
        //4封装为token对象
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password.toString());
        //4. 创建shiro的subject对象
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(usernamePasswordToken);//--------realm的login
        } catch (UnknownAccountException uae) {

            log.error("系统管理->用户登录  错误:{}", AdminResponseCode.ADMIN_INVALID_ACCOUNT_OR_PASSWORD.desc());
            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_ACCOUNT_OR_PASSWORD);

        } catch (LockedAccountException lae) {

            log.error("系统管理->用户登录 错误:{}", AdminResponseCode.ADMIN_LOCK_ACCOUNT.desc());
            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_LOCK_ACCOUNT);

        } catch (AuthenticationException ae) {
            log.error("系统管理->用户登录 错误:{}", AdminResponseCode.ADMIN_LOCK_ACCOUNT.desc());
            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_AUTH);
        }

        log.info("【请求结束】系统管理->用户登录,响应结果:{}", JSONObject.toJSONString(subject.getSession().getId()));
        return ResponseUtil.ok(subject.getSession().getId());


    }

    /**
     * 登录后获取用户名, 角色, 权限详细信息地址
     * {
     *     "errno":0,
     *     "data":{
     *         "roles":["超级管理员"],
     *         "name":"qianfeng",
     *         "perms":["*"],
     *         "avatar":"https://dss1.bdstatic.com/6OF1,499686101&fm=85&app=79&f=JPEG?w=121&h=75&s=81B24C32D40"
     *     },
     *     "errmsg":"成功"
     * }
     */
    @GetMapping("/info")
    public Object info(){
        Subject subject = SecurityUtils.getSubject();
        DtsAdmin dtsAdmin = (DtsAdmin) subject.getPrincipal();
        Map<String,Object> result = new HashMap<>();


        //3. 获取当前用户角色id数组
        Integer[] roleIds = dtsAdmin.getRoleIds();
        //4. 获取当前角色名字集合
        Set<String> roles = roleService.queryByIds(roleIds);
        //5. 获取当前权限字符串集合
        Set<String> permissions = permissionService.queryByRoleIds(roleIds);
        result.put("roles", roles);
        result.put("name", dtsAdmin.getUsername());
        result.put("perms",permissions);
        return ResponseUtil.ok(result);
    }

    /*
     * 用户注销
     */
    @RequiresAuthentication
    @PostMapping("/logout")
    public Object login() {
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();

        log.info("【请求结束】系统管理->用户注销,响应结果:{}", JSONObject.toJSONString(currentUser.getSession().getId()));
        return ResponseUtil.ok();
    }



}
